#include "udp_maker.h"

char *udp_maker(const uint16_t dport, const uint16_t sport,
                const uint16_t len, const uint8_t *buf,
                const int buf_len, const uint8_t *sip,
                const uint8_t *dip)
{
    if (len != (buf_len + 8))
    {
        ERR("udp maker param err udp pack len no eq head size + data size ");
        return NULL;
    }

    if (buf_len % 2 != 0)
    {
        ERR("udp data must align of 2");
        return NULL;
    }

    // 构造udp首部
    int head_len = sizeof(struct udphdr);
    struct udphdr head = {
        .check = 0,
        .dest = htons(dport),
        .source  = htons(sport),
        .len = htons(len),
    };
    // memcpy(&head.dest, dport, 2);
    // memcpy(&head.source, sport, 2);
    // memcpy(&head.len, len, 2);
    // memset(&head.check, 0, 2);

    int fake_head_len = sizeof(struct fake_udp_head);
    struct fake_udp_head fake_head ={
        .udp_len = htons(len),
        .zero = 0,
        .udp_proto_type = 0x11,
    };
    memcpy(fake_head.dip, dip, 4);
    memcpy(fake_head.sip, sip, 4);
    // memcpy(&(fake_head.udp_len), len, 2);
    // fake_head.zero = 0;
    // fake_head.udp_proto_type = 0x11;

    char *checksum_buf = malloc(fake_head_len + head_len + buf_len);
    memcpy(checksum_buf,&fake_head,fake_head_len);
    memcpy(checksum_buf+fake_head_len,&head,head_len);
    memcpy(checksum_buf+fake_head_len+head_len,buf,buf_len);
    uint16_t chsum =  pck_checksum(checksum_buf, fake_head_len + head_len + buf_len);
    memcpy(&head.check,&chsum,2);
    free(checksum_buf);

    // char *pck = malloc(head_len+buf_len);
    char *pck = malloc(head_len);
    memcpy(pck,&head,head_len);
    // memcpy(pck+head_len,buf,buf_len);
    return pck;
}

